package se.statifyme.server.servlet;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import se.statifyme.server.AccessService;
import se.statifyme.server.FilterMatcher;
import se.statifyme.server.FilterMatcher.Matcher;
import se.statifyme.shared.StringUtils;

public class AccessFilter implements Filter {

	private static final String CONFIG_TEST_ACCESS_URL = "testAccessUrlPattern";
	private static final String CONFIG_AVOID_URLS = "avoidUrlPatterns";
	
	private String testAccessUrlPattern;
	private FilterMatcher avoidURLFilter;
	
	public AccessFilter() {
		avoidURLFilter = new FilterMatcher(Matcher.REGEXP);
	}
	
	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String url = httpServletRequest.getServletPath();
		
		if (isTestPath(httpServletRequest)) {
			Logger.getLogger("StatifyMe").warning("Setting up test access.");
			AccessService.INSTANCE.setupTestAccess(request);
		}
		
		if (AccessService.INSTANCE.hasAccess(request) || avoidURLFilter.isMatch(url)) {

			Logger.getLogger("StatifyMe").warning("User is logged in or avoid URL: " + url);
			chain.doFilter(request, response);
		} else {
			Logger.getLogger("StatifyMe").warning("Re-directing due to no user logged in for path: " + url);
			((HttpServletResponse) response).sendRedirect("/login.jsp");
//			request.getRequestDispatcher("/index.jsp").forward(request, response);
		}
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		initTestAccessURL(config);
		initAvoidURLs(config);
	}

	private void initAvoidURLs(FilterConfig config) {
		String urls = config.getInitParameter(CONFIG_AVOID_URLS);
		if (StringUtils.isNotBlank(urls)) {
			Logger.getLogger("StatifyMe").warning("Initializing avoid URLs: " + urls);
			avoidURLFilter.addFilterPatterns(urls);
		}
	}

	private void initTestAccessURL(FilterConfig config) {
		String param = config.getInitParameter(CONFIG_TEST_ACCESS_URL);
		if (StringUtils.isNotBlank(param)) {
			testAccessUrlPattern = param;
			Logger.getLogger("StatifyMe").warning("Test access URL set to: " + testAccessUrlPattern);
		}
	}
	
	private boolean isTestPath(HttpServletRequest request) {
		boolean result = false;
		if (StringUtils.isNotBlank(testAccessUrlPattern)) {
			String fullUrl = getFullUrl(request);
			result = FilterMatcher.Matcher.REGEXP.isMatch(testAccessUrlPattern, fullUrl);
		}
		return result;
	}
	
	private String getFullUrl(HttpServletRequest request) {
		final StringBuffer result = request.getRequestURL();
		final String queryString = request.getQueryString();
		if (StringUtils.isNotBlank(queryString)) {
			result.append("?");
			result.append(queryString);
		}
		return result.toString();
	}
}
